package controllers;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

/**
 * Created by grzegorz on 10/28/14.
 */
public class HandEvaluation {
	
	/**
	 * Set generated to easly generate subsets of a hand
	 */
	private static int[][] powersetOfFour = new int[][]{
		{ 0 },
		{ 0, 1 },
		{ 0, 1, 2 },
		{ 0, 1, 2, 3 },
		{ 0, 1, 3 },
		{ 0, 2 },
		{ 0, 2, 3 },
		{ 0, 3 },
		{ 1 },
		{ 1, 2 },
		{ 1, 2, 3 },
		{ 1, 3},
		{ 2 },
		{ 2, 3 },
		{ 3 },
	};
	
	/**
	 * Public, static void method. Sort's array of cards. The result would be an array beginning from the best (lowest) cards.
	 * @param cards Array of cards (Card[])
	 */
	public static void sortCards( Card[] cards ) {
		for( int i = 0; i < cards.length; i++ ) {
			for( int j = i + 1; j < cards.length; j++ ) {
				if( cards[ i ].getRank().ordinal() > cards[ j ].getRank().ordinal() ) {
					Card temp = cards[ i ];
					cards[ i ] = cards[ j ];
					cards[ j ] = temp;
				}
			}
		}
	}	
	/**
	 * @param hand1 1st hand to be compared
	 * @param hand2 2nd hand to be compared
	 * @return 1 if hand1 is better, 2 if hand2 is better, 0 if hand1 is equal to hand2
	 */
	private static Card[] compareHands(Card[] hand1, Card[] hand2){
		int handLength1 = hand1.length;
		int handLength2 = hand2.length;
		if( handLength1 > handLength2 ) {
			return hand1;
		}
		else if( handLength1 < handLength2 ) {
			return hand2;
		}
		else  {
			for( int i = handLength1-1; i >= 0; i-- ) {
				if( hand1[ i ].getRank().ordinal() < hand2[ i ].getRank().ordinal() ){
					return hand1;
				}
				else if( hand1[ i ].getRank().ordinal() > hand2[ i ].getRank().ordinal() ){
					return hand2;
				}
			}
		}
		return new Card[ 0 ];
	}
	/**
	 * Method that finally decides which hand is better.
	 * @param hand1
	 * @param hand2
	 * @return
	 */
	public static Card[] evaluateHands(Card[] hand1, Card[] hand2){
		//Generate powersets
		ArrayList<Card[]>hand1PS = powerSet(hand1);
		ArrayList<Card[]>hand2PS = powerSet(hand2);
		// Time to sort the sets
		sortArray(hand1PS);
		sortArray(hand2PS);
		return compareHands(hand1PS.get(0), hand2PS.get(0));
	}
	
	public static ArrayList<Card[]> powerSet(Card[] hand) {
		ArrayList<Card[]>handPS = new ArrayList<Card[]>();
		Card[] handSS;
		boolean repeat = false;
		for (int i = 0; i < 15; i++){
			handSS = new Card[HandEvaluation.powersetOfFour[i].length];
			for (int j = 0; j<handSS.length; j++){
				handSS[j] = hand[HandEvaluation.powersetOfFour[i][j]];
			}
			for (int j = 0; j < handSS.length-1; j++){
				for (int l = j+1; l < handSS.length; l++){
					if (handSS[j].getRank() == handSS[l].getRank()){
						repeat = true;
					}else if (handSS[j].getSuit() == handSS[l].getSuit()){
						repeat = true;
					}
				}
				if (repeat){
					break;
				}
			}
			if (!repeat){
				sortCards( handSS );
				handPS.add(handSS);
			}
			repeat = false;
		}
		return handPS;
	}
	
	public static void sortArray(ArrayList<Card[]> powerSet) {
		int n = powerSet.size();
		Card[] temp;
		do{
			for (int i = 0; i < n-1; i++){
				if (compareHands(powerSet.get(i), powerSet.get(i+1)) == powerSet.get( i + 1 ) ) {
					temp = powerSet.get(i);
					powerSet.set(i, powerSet.get(i+1));
					powerSet.set(i+1, temp);
				}
			}
			n=n-1;
		}while(n>1);
	}
}
